#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <condition_variable>
#include <atomic>


class EventSignal
{
private:
  /* data */
  uint32_t event_ = 0;

  std::mutex mutex_;

  std::condition_variable var_;

  std::atomic<bool> is_set_flag_;

public:
  EventSignal(/* args */): is_set_flag_(false){
    event_ = 0;
  };
  ~EventSignal();

  void Set()
  {
    Set(0);
  };

  void Set(uint32_t signal)
  {
    is_set_flag_ = true;
    event_ |= signal;
    var_.notify_all();
  };

  void Set(uint32_t event_bit, uint32_t all_event)
  {
    event_ |= event_bit;
    if(all_event == event_){
      is_set_flag_ = true;
      var_.notify_all();
    }
  }

  void SetAll(uint32_t event)
  {
    event_ = event;
    is_set_flag_ = true;
    var_.notify_all();
  }

  uint32_t Wait(uint32_t timeout)
  {
    
    std::unique_lock<std::mutex> lock(mutex_);
    bool ret = false;
    
    ret = var_.wait_for(lock, std::chrono::milliseconds(timeout), [&] { return is_set_flag_ == true;});
    
    uint32_t event = ret ? event_ : -1;

    event_ = 0;
    is_set_flag_ = false;
    
    return event;
  };
};


int main(int argc, char **argv)
{
  
}
